package com.asura.app.library.initializer;

import android.content.Context;
import android.os.Looper;

import com.asura.app.library.utils.ExecutorHelper;
import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;


/**
 * Created by Asura on 2017/4/1.
 */

public class InitializeProcessor {
    private List<Initializer> backgroundInitializers;
    private List<Initializer> foregroundInitializers;
    private volatile boolean isInited;

    public InitializeProcessor() {
        backgroundInitializers = new ArrayList<>();
        foregroundInitializers = new ArrayList<>();
    }

    public void process(Context context, boolean debuggable) {
        if (Looper.getMainLooper() != Looper.myLooper()) {
            throw new IllegalStateException("you have to call this on main thread");
        }
        for (Initializer initializer : foregroundInitializers) {
            try {
                initializer.initialize(context, debuggable);
            } catch (Exception e) {
                Logger.e(e, initializer.getClass() + "初始化失败");
            }
        }
        Flowable.fromIterable(backgroundInitializers)
                .flatMap(initializer -> Flowable.fromCallable(
                        () -> {
                            initializer.initialize(context, debuggable);
                            return true;
                        }).subscribeOn(Schedulers.from(ExecutorHelper.LOW))
                )
                .toList()
                .toCompletable()
                .doOnError(throwable -> Logger.e(throwable, "初始化失败"))
                .doOnComplete(() -> isInited = true)
                .subscribe();
    }

    public void registerInitializer(Initializer initializer) {
        registerInitializer(initializer, false);
    }

    public void registerInitializer(Initializer initializer, boolean background) {
        if (background) {
            backgroundInitializers.add(initializer);
        } else {
            foregroundInitializers.add(initializer);
        }
    }

    public boolean isInited() {
        return isInited;
    }
}
